<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //原型: 每个对象都会在其内部初始化一个属性，就是prototype(__proto__原型)

        //__proto__  指的是原型对象，一个普通的对象

        //Object.prototype  是null

        //实例 有的是__proto__  
        //构造函数：prototype
        //
        // let obj = {name:'lili'}; // let obj = new Object()  

        // console.log(obj.hasOwnProperty('name'));

        // let arr = [1];  //let arr = new Array();

        // console.log(arr);

        // arr.push(3);

        // let a = new String('aaa');
        // console.log(a);
        // console.log(a.xx);
        // //a.__proto__ === String.prototype
        // a.substr(1);
        // // console.log(a.__proto__.__proto__.__proto__)

        // console.log(a.hasOwnProperty('substr'))

        //es5
        // function Person(name){
        //     this.name = name;
        // }

        // Person.prototype.sayName = function(){
        //     console.log(this.name);
        // }

        // let p1 = new Person('zs'); //p1  



        // //1.new Person()  2.Person()


        // function createNew(){
        //     //1.声明空对象
        //     let obj = {};
        //     //arguments
        //     let Con = arguments[0];  //2.拿到构造函数

        //     obj.__proto__ = Con.prototype; //3.把构造函数的原型对象给到obj的__proto__

        //     let args = [...arguments].slice(1);

        //     Con.apply(obj,args);

        //     return obj
        // }

        // let p2 = createNew(Person,'zs');


        // console.log(p1)
        
        // console.log(p2)

        // console.log(p1.__proto__ === Person.prototype);

        //==============================================

        //es6 类  class  extends

        //es5 继承 ： 1.借用构造函数  2.原型继承   3.借用构造函数+原型  4....


        function Person(name,age){
            this.name = name;
            this.age = age;
        }

        Person.prototype.sayName = function(){
            console.log(this.name);
        }

        ///1.借用构造函数
        // function Student(name,age){
        //     // Person.call(this,name,age)
        // }

        // let p1 = new Person('zs',18);

        // let s1 = new Student('lisi',19);

        // console.log(p1,s1);

        //2.原型链继承

        // function Student(name,age){
        //     Person.call(this,name,age)
        // }

        // Student.prototype = Person.prototype;

        // let p1 = new Person('zs',18);

        // let s1 = new Student('lisi',19);

        // console.log(p1,s1);

        // let obj = {name:'ss'};


        // function fn(){
        //     console.log(this);
        // }

        // Function.prototype.myCall = function(context){
        //     if(typeof this !== 'function'){
        //         throw new Error('error');
        //     }

        //     context = context || window;

        //     context.fn = this; //fn

        //     let args = [...arguments].slice(1);

        //     let result = context.fn(...args);
            
        //     delete context.fn;

        //     return result

        // }

        // fn.myCall(obj,1,2);

        //箭头函数和普通函数的区别：1.写法上，省略   2.普通函数有arguments   箭头函数：没有arguments  ...rest 

        //3.this指向不一样   //4.箭头函数不能用new调用 ，普通函数可以用new调用  

        // const fn = num =>  num*2


        // function fn(){
        //     console.log(this)
        // }

        // fn(1,2,3,4)


        const fn = () => {
            console.log(this)
        }

        // fn(1,2,3,4)

        // new Fn(1,2,3)

        fn.call({name:'12'})
        
    </script>
</body>
</html>